#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
using namespace std;
int i, x;
int main()
{
    vector<int> a(10, 3); // 定义一个长度为10的vector，它里面每个长度都是3

    // 每个容器都有，时间复杂度O(1)
    // vector容器特有的
    a.size();       // 容器里元素的个数
    a.empty();      // a是不是空的，空则True，非空则false
    a.clear();      // 清空
    a.front();      // 返回第一个数
    a.back();       // 返回最后一个数
    a.push_back(i); // 向vector最后插入一个数
    a.pop_back();   // 删掉vector最后一个数
    a.begin();      // vector第0个数,即a[0]（迭代器）
    a.end();        // vector最后一个数的后一个数,即a[a.size()]（迭代器）

    // 三种遍历方式
    for (int i = 0; i < a.size(); i++)
        cout << a[i] << ' '; // 数组遍历
    for (vector<int>::iterator i = a.begin(); i != a.end(); i++)
        cout << *i << ' '; // 迭代器遍历
    for (auto x : a)
        cout << x << ' '; // auto自动推断变量类型

    // 比较运算（字典顺序）
    vector<int> a(4, 3), b(3, 4); // 字典顺序a四个3小于b三个4
    if (a < b)
        puts("a<b");





    pair<int, string> p;
    p.first();  // 第一个元素
    p.second(); // 第二个元素

    // 初始化
    p = make_pair(10, "abc");
    p = {20, "def"};

    // 比较运算，以first为第一关键字，以second为第二关键字（字典顺序）

    // 存储多种东西（以3个3种为例）
    pair<int, pair<float, string>> // pair中存储pair来实现





	string a = "abc";          // 字符串赋值
    a.size();                  // a的大小
        a.length();                // a的大小
    a.empty();                 // a是否为空
    a.clear();                 // 清空a
    a += "def";                // 字符串相加
    a += "c";                  // 字符串和字符相加
    a.substr(1, 2);            // 返回下标从1开始长度为2的字符串
    a.substr(1, 10);           // 下标超出就到最后一个字符为止
    a.substr(1);               // 返回下标从1开始的字符串
    a.c_str();                 // 返回字符数组的起始地址
    printf("%s\n", a.c_str()); // 用字符数组的起始地址打印字符串





    queue<int> q;
    q.size();
    q.empty();
    // queue没有clear，想清空可以直接赋值：q=queue<int>();
    q.push();  // 向队尾插入一个数
    q.front(); // 返回队头元素
    q.back();  // 返回队尾元素
    q.pop();   // 弹出队头元素





    priority_queue<int> heap;
    // 默认大根堆
    priority_queue<int, vector<int>, greater<int>> heap;
    // 定义小根堆
    heap.push(); // 插入一个元素
    heap.top();  // 返回堆顶元素
    heap.pop();  // 弹出堆顶元素





    stack<int> s;
    s.size();
    s.empty();
    // 没有clear
    s.push(); // 向栈顶插入一个元素
    s.top();  // 返回栈顶元素
    s.pop();  // 弹出栈顶元素





    deque<int> q;
    q.size();
    q.empty();
    q.clear();
    q.front();      // 返回队头元素
    q.back();       // 返回队尾元素
    q.push_back();  // 向队尾插入一个数
    q.pop_back();   // 弹出队尾元素
    q.push_front(); // 向队头插入一个数
    q.pop_front();  // 弹出队头元素
    q.begin();      // deque第0个数,即q[0]（迭代器）
    q.end();        // deque最后一个数的后一个数,即q[q.size()]（迭代器）
    int p = q[1];   // 支持随机寻址





    set<int> s;
	multiset<int> ms;
	s.size(), ms.size();
	s.empty(), ms.empty();
	s.clear(), ms.clear();
	s.begin(), ms.begin();   // 迭代器（++和--可返回前驱和后继 log n）
	s.end(), ms.end();       // 迭代器（++和--可返回前驱和后继 log n）
	s.insert(), ms.insert(); // 插入一个数
	s.find(), ms.find();     // 查找一个数
	s.count(), ms.count();   // 返回某一个数的个数
	
	
	// 擦除
	s.erase(), ms.erase();
	// 1.输入是一个数，删除所有的x  O(k（个数）*log n)
	// 2.输入一个迭代器，删除这个迭代器
	
	s.lower_bound(x), ms.lower_bound(x); // 返回大于等于x的最小数的迭代器
	s.upper_bound(x), ms.upper_bound(x); // 返回大于x的最小的数的迭代器





	map<string, int> m;
	multimap<string, int> mm;
	m.size(), mm.size();
	m.empty(), mm.empty();
	m.clear(), mm.clear();
	m.begin(), mm.begin();   // 迭代器（++和--可返回前驱和后继 log n）
	m.end(), mm.end();       // 迭代器（++和--可返回前驱和后继 log n）
	m.insert(), mm.insert(); // 插入的数是一个pair
	m.find(), mm.find();
	m.erase(), mm.erase();   // 输入的参数是pair或者迭代器
	
	//插入与查找
	m["abc"]=1;  //O(log n)
	cout<<m["abc"];
	
	m.lower_bound(x), mm.lower_bound(x); // 返回大于等于x的最小数的迭代器
	m.upper_bound(x), mm.upper_bound(x); // 返回大于x的最小的数的迭代器




    
    bitset<10000> s, t; // 开长度为10000的bitset（bool类型）
    ~s, s &t, s | t, s ^ t; // 对整体进行位运算（取反，与，或，亦或）
    s << 1, s >> 2;         // 看作整体进行移位
    s == t, s != t;         // 比较
    s[i] = 0;               // 取出第i位进行操作
    s.count();              // 返回有多少个1
    s.any();                // 判断是否有至少一个1
    s.none();               // 判断是否全为0
    s.set();                // 把所有位置为1
    s.set(k, v);            // 将第k位置为v
    s.reset();              // 把所有位置为0
    s.flip();               // 取反
    s.flip(k);              // 把第k位取反
}